package cn.jd.service.impl;

import cn.jd.domain.Product;
import cn.jd.domain.PurchaseApply;
import cn.jd.domain.Stock;
import cn.jd.domain.StockWarningLog;
import cn.jd.dto.StockDto;
import cn.jd.enums.GlobalExceptionCode;
import cn.jd.exception.GlobalCustomException;
import cn.jd.feign.ProductService;
import cn.jd.feign.PurchaseApplyService;
import cn.jd.mapper.StockMapper;
import cn.jd.mapper.StockWarningLogMapper;
import cn.jd.properties.StockThresholdProperties;
import cn.jd.result.JSONResult;
import cn.jd.service.IStockService;
import cn.jd.service.IStockWarningLogService;
import cn.jd.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zyg
 * @since 2022-09-29
 */
@Service
public class StockServiceImpl<wrapper, selectList> extends ServiceImpl<StockMapper, Stock> implements IStockService {
    @Autowired
    private ProductService productService;
    @Autowired
    private StockThresholdProperties stockThresholdProperties;
    @Autowired
    private IStockWarningLogService stockWarningLogService;
    @Autowired
    private PurchaseApplyService purchaseApplyService;

    @Override
    public void outInStock(StockDto stockDto) {
         Stock stock =  selectStock(stockDto.getProductId());
        // 入库
         if (stockDto.getStatus() == 0) {
             if (stock == null) {
                 stock = new Stock();
                 stock.setCount(stockDto.getCount());
                 stock.setProductId(stockDto.getProductId());
                 JSONResult jsonResult = productService.get(stockDto.getProductId());
                 AssertUtil.isTrue(jsonResult.isSuccess(), GlobalExceptionCode.ERROR);
                 Object data = jsonResult.getData();
                 AssertUtil.isNotNull(data,GlobalExceptionCode.ERROR);
                 String jsonString = JSONObject.toJSONString(data);
                 // 添加商品信息
                 addProduct(stock, jsonString);
             } else {
                 stock.setCount(stock.getCount() + stockDto.getCount());
                 updateById(stock);
             }
             // 出库
         } else {
             Integer count = stock.getCount();
             // 当库存小于出库的数量时
             if (count < stockDto.getCount()) {
                 Date date = new Date();
                 // 再判断库存是否低于阈值
                 if (count < stockThresholdProperties.getThreshold()) {
                     // 低于阈值的添加到警告日志
                     addWarningLog(stock, date);
                     // 提供采购服务
                     purchase(stock, date);
                     // 库存充足时
                 } else {
                     stock.setCount(stock.getCount() - stockDto.getCount());
                     updateById(stock);
                     // 调用提供采购服务
                     purchase(stock, date);
                 }
             }

         }
    }

    private void addProduct(Stock stock, String jsonString) {
        Product product = JSON.parseObject(jsonString, Product.class);
        stock.setProductName(product.getProductName());
        stock.setCreateTime(new Date());
        insert(stock);
    }

    private void addWarningLog(Stock stock, Date date) {
        StockWarningLog stockWarningLog = new StockWarningLog();
        BeanUtils.copyProperties(stock,stockWarningLog);
        stockWarningLog.setCreateTime(date);
        stockWarningLog.setInfo(stockWarningLog.getProductName()+"库存不足，请及时进货！");
        stockWarningLogService.insert(stockWarningLog);
    }

    private void purchase(Stock stock, Date date) {
        // 提供采购服务
        PurchaseApply purchaseApply = new PurchaseApply();
        BeanUtils.copyProperties(stock, purchaseApply);
        purchaseApply.setCreateTime(date);
        purchaseApply.setStatus(0);
        purchaseApply.setCount(200);
        purchaseApplyService.saveOrUpdate(purchaseApply);
        throw new GlobalCustomException(GlobalExceptionCode.STOCK_IS_NOT_ENOUGH);
    }

    @Override
    public List<Stock> lack() {
        // 获取库存的阈值
        Integer threshold = stockThresholdProperties.getThreshold();
        EntityWrapper<Stock> wrapper = new EntityWrapper<>();
        wrapper.lt("count", threshold);
        List<Stock> stocks = selectList(wrapper);
        return stocks;
    }

    private Stock selectStock(Long productId) {
        Wrapper<Stock> wrapper = new EntityWrapper<>();
        wrapper.eq("product_id",productId);
        return selectOne(wrapper);
    }
}
